#include <kernel.h>

physaddr_t 
sc_ppage_alloc(int num, int dma)
{
	 physaddr_t paddr;
	 if (ekf_pmem_page_alloc(num, &paddr, dma, EKF_PPAGE_MANAGED) != 0)
		  return 0;
	 else return paddr;
}

int
sc_ppage_free(physaddr_t paddr)
{
	 ekf_pmem_page_free(paddr);
	 return 0;
}

physaddr_t
sc_mmap_get(void *addr)
{
	 physaddr_t paddr;
	 ekf_mmap_get(addr, &paddr, NULL, NULL);
	 return paddr;
}

int
sc_mmap_set(void *addr, physaddr_t paddr)
{
	 ekf_mmap_set(addr, paddr, 1, 1);
	 return 0;
}

uint32_t
sc_process_io_buffer(uint32_t *buf, uint32_t count)
{
	 if (count == 0)
		  proc_legacy_wait_try();
	 
	 uint32_t r = 0;
	 uint32_t w = 0;
	 while (r < count)
	 {
		  uint32_t uevent  = buf[r ++];
		  uint32_t func = buf[r ++];

		  switch (func)
		  {
		  case SC_KPRINTF:
		  {
			   uint32_t fmt = buf[r ++];
			   uint32_t va  = buf[r ++];
			   
			   ekf_vkprintf((const char *)fmt, (va_list)va);

			   buf[w ++] = uevent;
			   break;
		  }
		  case SC_DUMMY_WORK:
		  {
			   uint32_t workset_pages = buf[r ++];
			   // REMOVED
			   // dummy_work(workset_pages);
			   buf[w ++] = uevent;

			   break;
		  }
		  case SC_UEVENT_TOUCH:
		  {
			   proc_event_t e = uevent_get(uevent);
			   buf[w ++] = uevent;
			   
			   break;
		  }
		  case SC_UEVENT_ACTIVATE:
		  {
			   uint32_t ue = buf[r ++];
			   proc_event_t e = uevent_find(ue);

			   if (e != NULL) proc_event_activate(e);
			   buf[w ++] = uevent;
			   break;
		  }
		  default:
			   ekf_kprintf("PROCESS IO BUFFER: UNKNOWN IOCALL %d\n", func);
			   break;
		  }
	 }
	 return w;
}

void
sc_dummy_work(int workset_pages)
{
	 /* REMOVED */
}

void
sc_exam_addr(void *addr)
{
	 pdir_entry_t pde = vpd[PAGEDIR_IDX(addr)];
	 if (pde & PTE_P)
	 {
		  ekf_kprintf("%08x PDE %08x PTE %08x\n", addr, pde, vpt[PAGE_NUM(addr)]);
	 }
	 else
	 {
		  ekf_kprintf("%08x PDE %08x\n", addr, pde);
	 }
}

void
sc_yield(void)
{
	 proc_yield();
}
